import { CHint } from "./CHint";
import { MsgCallback } from "./Constant";
import { Singleton } from "./Singleton";

export class SocketMgr extends Singleton {
    private socket: Laya.Socket = null;
    private token: string = "LOe3xAZozFFICrqoutIpyc2_eQn_W-bQfQnSmEqOBlcK0cOb8cS2f0AJJWMDt7bxHndolZC8CizjlTZ41UlZf_p3WgTkLC9h-K4j9TV6pkbZtzyDZ_ThcOqdVMT4xDJZ";
    private baseUrl: string = "175.27.156.196";
    private url: string = "";
    private isSecure = false;
    private eventListeners: Array<MsgCallback> = [];
    private pushListeners: Array<MsgCallback> = [];

    connect(token?: string, callback?: Laya.Handler) {
        if (token) {
            this.token = token;
        }
        console.log("window.location.hostname = " + window.location.hostname);
        if (window.location.hostname != "localhost") {
            this.baseUrl = window.location.hostname;
        }
        this.isSecure = window.location.protocol == "https:";
        if (this.isSecure) {
            this.url = `wss://${this.baseUrl}/api/business/ws/info?access_token=${this.token}`;
        } else {
            this.url = `ws://${this.baseUrl}/api/business/ws/info?access_token=${this.token}`;
        }
        console.log(this.url);
        this.socket = new Laya.Socket();
        this.socket.on(Laya.Event.OPEN, (evt: any) => {
            callback && callback.runWith(evt);
            this.startPing();
        });

        this.socket.on(Laya.Event.MESSAGE, (data: any) => {
            if (typeof data == "string") {
                data = JSON.parse(data);
            }
            if ((data.status != void 0 && data.countdownType == void 0) || data.code != void 0) {
                console.log(data);
            }
            for (let i = 0; i < this.eventListeners.length; i++) {
                if (data.status && this.eventListeners[i].status == data.status) {
                    this.eventListeners[i].callback && this.eventListeners[i].callback.call(this.eventListeners[i].caller, data);
                    this.eventListeners.splice(i, 1);
                    break;
                }
            }

            if (data.code > 10000) {
                CHint.getInstance().showText(data.msg);
                return;
            }

            for (let i = 0; i < this.pushListeners.length; i++) {
                if (this.pushListeners[i].code == data.code) {
                    this.pushListeners[i].callback && this.pushListeners[i].callback.call(this.pushListeners[i].caller, data);
                }
            }
        });


        this.socket.on(Laya.Event.CLOSE, () => {
            console.log("ws disconnect");
            this.reconnect();
        });


        this.socket.on(Laya.Event.ERROR, () => {

        });

        this.socket.connectByUrl(this.url);
    }

    send(data: any, callback?: Function, caller?: any) {
        if (this.socket && this.socket.connected) {
            console.log(data);
            let str = JSON.stringify(data);
            if (data.status)
                this.eventListeners.push({ status: data.status, callback: callback, caller: caller });
            // this.socket.send(data);
            this.socket.send(str);
        }
    }

    close() {
        if (this.socket)
            this.socket.close();
    }

    reconnect() {
        this.close();
        Laya.timer.once(2000, this, this.connect);
    }

    addEventListener(msgCode: number, callback: Function, caller?: any) {
        this.pushListeners.push({ code: msgCode, callback: callback, caller: caller });
    }

    removeEventListener(msgCode: number) {
        for (let i = 0; i < this.eventListeners.length; i++) {
            if (this.eventListeners[i].code == msgCode) {
                this.eventListeners.splice(i, 1);
                break;
            }
        }

        for (let i = 0; i < this.pushListeners.length; i++) {
            if (this.pushListeners[i].code == msgCode) {
                this.pushListeners.splice(i, 1);
                break;
            }
        }
    }

    removeEventListenerByCaller(caller: any) {
        for (let i = this.eventListeners.length - 1; i >= 0; i--) {
            if (this.eventListeners[i].caller == caller) {
                this.eventListeners.splice(i, 1);
            }
        }

        for (let i = this.pushListeners.length - 1; i >= 0; i--) {
            if (this.pushListeners[i].caller == caller) {
                this.pushListeners.splice(i, 1);
            }
        }
    }

    public set Token(token: string) {
        this.token = token;
    }

    public get Token(): string {
        return this.token;
    }

    startPing() {
        Laya.timer.clear(this, this.sendPing);
        Laya.timer.loop(5000, this, this.sendPing);
    }

    private sendPing() {
        this.send({ type: "ping" }, (_data: any) => {
        });
    }
}